<template>
  <div class="editPage__video">
    <div class="img__con">
      <template v-if="uploadVideo.url">
        <el-button
          style="width: 60px"
          type="danger"
          size="mini"
          icon="el-icon-close"
          @click="handleDelete"
        />
      </template>
      <el-upload
        class="avatar-uploader"
        :action="`/api/not404`"
        :http-request="uploadHttp"
        :show-file-list="false"
        :before-upload="handleBeforeUpload"
        :headers="headers"
      >
        <template v-if="uploadVideo.url">
          <video :key="menuKey" width="200" height="200" controls="controls">
            <source :src="uploadVideo.url" type="video/mp4">
          </video>
        </template>
        <template v-else>
          <el-button>上传<i class="el-icon-upload el-icon--right" /></el-button>
        </template>
      </el-upload>
      <p class="font-12 font-color-2"> 说明: 视频格式为{{ supportFileTypeStr }}格式，视频大小不超过{{ maxSize }}MB</p>
      <template v-if="filePlanList.length > 0">
        <div class="plan-nav">
          <div v-for="item in filePlanList" :key="item.fileName" class="plan-item">
            <p class="font-color font-14">{{ item.fileName }}</p>
            <p class="ml-10 mr-10">/</p>
            <p class="font-color font-14 mr-50">{{ item.fileSize }}MB</p>
            <template v-if="item.progress">
              <el-progress :percentage="item.progress" />
            </template>
            <template v-else>
              <i class="el-icon-loading" />
            </template>
          </div>
        </div>
      </template>
    </div>
  </div>
</template>

<script>
import { queryGetStsToken } from '@/api/oss/oss'
import OSS from 'ali-oss'
import { getToken } from '@/utils/auth'

export default {
  props: {
    videoSrc: {
      type: String,
      default: ''
    },
    video_folder: {
      type: String,
      default: ''
    },
    oss_type: {
      /**
       * video_main 短剧库的每一集
       * material 素材库
       * */
      type: String,
      default: 'video_main'
    },
    // 最大视频大小  单位MB
    maxSize: {
      type: Number,
      default: 2000
    },
    // 支持的文件类型
    supportFileType: {
      type: Array,
      default: () => ['mp4']
    }
  },
  data() {
    return {
      uploadVideo: {},
      menuKey: 1, // 用来强制刷新
      headers: {
        Authorization: 'Bearer ' + getToken()
      },
      fileList: [],
      filePlanList: [], // 上传状态，仅展示
      client: {}
    }
  },
  computed: {
    supportFileTypeStr() {
      return this.$props.supportFileType.toString()
    }
  },
  watch: {
    videoSrc: {
      handler(val) {
        this.menuKey++
        this.uploadVideo.url = val
        this.$forceUpdate()
      },
      immediate: true,
      deep: true
    }
  },
  created() {
    this.queryGetStsTokenFn()
  },
  methods: {
    handleBeforeUpload(file) {
      const { name } = file
      let nameTemp = name.split('.')[0]
      nameTemp = Number(nameTemp)
      if (!Number.isInteger(nameTemp)) {
        // 重命名只能是阿拉伯数字
        this.$modal.msgError('视频重命名错误，请检查')
        return false
      }

      const isMov = file.type === 'video/quicktime'
      const isMp4 = file.type === 'video/mp4'
      const { maxSize } = this.$props
      // 限制文件最大不能超过 300MB
      const isLt2M = file.size / 1024 / 1024 < maxSize

      if (!isMp4 && !isMov) {
        this.$modal.msgError(`视频只能是${this.supportFileTypeStr}格式!`)
      }
      if (!isLt2M) {
        this.$modal.msgError(`上传视频大小不能超过 ${maxSize}MB!`)
      }
      return (isMp4 || isMov) && isLt2M
    },
    // 删除视频
    handleDelete() {
      this.uploadVideo = {}
      this.$emit('update:ossId', '')
    },

    // 上传成功回调
    handleUploadSuccess(fileName, id, url) {
      this.uploadVideo = { name: fileName, id: id, url: url }
      this.$emit('update:ossId', id)
      this.filePlanList = []
    },

    // 获取oss的sts令牌
    async queryGetStsTokenFn() {
      const res = await queryGetStsToken()
      const {
        AccessKeyId,
        AccessKeySecret,
        Expiration,
        SecurityToken
      } = res

      const client = new OSS({
        // yourRegion填写Bucket所在地域。以华东1（杭州）为例，yourRegion填写为oss-cn-hangzhou。
        region: 'oss-cn-shenzhen',
        // 从STS服务获取的临时访问密钥（AccessKey ID和AccessKey Secret）。
        accessKeyId: AccessKeyId,
        accessKeySecret: AccessKeySecret,
        // 从STS服务获取的安全令牌（SecurityToken）。
        stsToken: SecurityToken,
        // 填写Bucket名称，例如examplebucket。
        bucket: 'playlet-video-asset'
      })
      this.client = client
    },

    // 上传
    async uploadHttp(event) {
      const file = event.file
      const name = event.file.name
      const fileName = '/tmp/' + name

      const sizeMB = Math.trunc(file.size / 1024 / 1024)
      this.filePlanList = []
      this.filePlanList.push({
        fileName: file.name,
        fileSize: sizeMB
      })

      let duration = 0
      const { oss_type, video_folder } = this.$props
      // 传入file
      const binaryData = [file]
      // 获取视频或者音频时长
      const fileUrl = URL.createObjectURL(new Blob(binaryData, { type: 'application/zip' }))
      // 经测试，发现audio也可获取视频的时长
      const audioElement = new Audio(fileUrl)
      const durationPromise = new Promise(resolve => {
        audioElement.addEventListener('loadedmetadata', function(_event) {
          duration = audioElement.duration
          console.log('视频的时长为:', duration)// 单位：秒
          resolve(duration)
        })
      })
      durationPromise.then(duration => {
        const options = {
          // 获取分片上传进度、断点和返回值。
          progress: (p, cpt, res) => {
            // console.log(p)
            const temp = p * 100
            this.filePlanList[0].progress = Math.trunc(temp)
            this.$forceUpdate()
          },
          // 设置并发上传的分片数量。
          parallel: 4,
          // 设置分片大小。默认值为1 MB，最小值为100 KB。
          partSize: 1 * 1024 * 1024, // 1MB
          // headers,
          // 自定义元数据，通过HeadObject接口可以获取Object的元数据。
          // meta: { year: 2020, people: 'test' },
          mime: 'video/mp4',
          callback: {
            // 设置回调请求的服务器地址，且要求必须为公网地址。
            url: process.env.VUE_APP_BASE_API + '/common/oss/ossCallBack',
            // 设置回调请求消息头中Host的值，即您的服务器配置的Host值。
            // host: 'yourHost',
            // 设置发起回调时请求body的值。
            body: 'bucket=${bucket}&object=${object}&etag=${etag}&size=${size}&mimeType=${mimeType}&imageInfo_height=0&imageInfo_width=0&imageInfo.format=${imageInfo.format}&type=${x:type}&video_duration=${x:video_duration}&library_dir=${x:library_dir}',
            // 设置发起回调请求的Content-Type。
            contentType: 'application/x-www-form-urlencoded',
            // 设置发起回调请求的自定义参数。
            // 测试
            customValue: {
              type: oss_type, // 接口对应的类型
              video_duration: Math.ceil(duration).toString(),
              library_dir: video_folder
            }
          }
        }
        // object-name可以自定义为文件名（例如file.txt）或目录（例如abc/test/file.txt）的形式，实现将文件上传至当前Bucket或Bucket下的指定目录。
        this.client.multipartUpload(fileName, file, options).then(res => {
          console.log('阿里云直传成功，后端逻辑处理成功=', res)
          const data = res.data.data
          const { id, url } = data
          this.handleUploadSuccess(name, id, url)
          // 一下为生成图片处理的签名 URL t_1000表示第一秒视频图片，常用来作为视频封面图
          // const imgRes = this.video_url + '?x-oss-process=video/snapshot,t_1000,f_jpg,w_0,h_0,m_fast'
        }).catch((err) => {
          console.error(err)
        })
      })
    }

  }
}
</script>

<style lang="scss" scoped>
.editPage__video {
  .avatar-uploader .el-upload {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
  }

  .avatar-uploader .el-upload:hover {
    border-color: #409eff;
  }

  .avatar-uploader-icon {
    font-size: 16px;
    color: #8c939d;
    width: 350px;
    height: 30px;
    line-height: 30px;
    text-align: center;
  }

  .avatar {
    width: 350px;
    height: auto;
    display: block;
  }

  .title {
    font-size: 18px;
    margin-bottom: 20px;
  }

  .img__con {

    .el-button {
      width: 100%;
      margin: 10px 0 20px 0;
    }
  }
}

.plan-nav {
  margin-top: 22px;
  max-height: 360px;
  overflow-y: scroll;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  .plan-item {
    display: flex;
    align-items: center;
    width: 100%;
  }
  ::v-deep .el-progress {
    flex: 1;
  }
  ::v-deep .el-progress-bar {
    flex: 1;
  }
  .file-name-p {
    color: #333333;
    font-size: 14px;
    margin-right: 20px;
  }
}
.plan-nav:after {
  content: '';
  width: 33%;
}
.plan-nav::-webkit-scrollbar {
  width: 4px;
}
.plan-nav::-webkit-scrollbar-thumb {
  border-radius: 10px;
  background: rgba(0,0,0,0.2);
}
.plan-nav::-webkit-scrollbar-track {
  border-radius: 0;
  background: rgba(0,0,0,0.1);
}
</style>
